import "./App.css";
import { useState, useEffect, useMemo } from "react";
import * as XLSX from "xlsx";
import { ConfigProvider, InputNumber, Button } from "antd";

function App() {
  const [value, onChange] = useState<any>();
  const [count, setCount] = useState<any>();
  const [excelData, setExcelData] = useState<any[]>([]);

  const item = useMemo<any>(
    () =>
      excelData.find((item) => item.score === Math.floor(count)) ||
      excelData[excelData.length - 1],
    [count, excelData]
  );

  const itemNext = useMemo<any>(
    () =>
      excelData.find((item) => item.score === Math.ceil(count)) ||
      excelData[excelData.length - 1],
    [count, excelData]
  );

  const itemLast = useMemo<any>(
    () => excelData[excelData.length - 1],
    [excelData]
  );

  const rankRatio = useMemo<any>(
    () =>
      !count
        ? null
        : Number(
            (
              (1 -
                (itemNext.allAble +
                  (item.allAble - itemNext.allAble) *
                    (Math.ceil(count) - count)) /
                  itemLast.allAble) *
              100
            ).toFixed(2)
          ),
    [count, item, itemNext, itemLast]
  );

  const rankSixRatio = useMemo<any>(
    () =>
      !count
        ? null
        : Number(
            (
              (1 -
                (itemNext.sixAble +
                  (item.sixAble - itemNext.sixAble) *
                    (Math.ceil(count) - count)) /
                  itemLast.sixAble) *
              100
            ).toFixed(2)
          ),
    [count, item, itemNext, itemLast]
  );

  const rank = useMemo<any>(
    () =>
      !count
        ? null
        : Math.round(
            itemNext.allAble +
              (item.allAble - itemNext.allAble) * (Math.ceil(count) - count)
          ),
    [count, item, itemNext]
  );
  const rankSix = useMemo<any>(
    () =>
      !count
        ? null
        : Math.round(
            itemNext.sixAble +
              (item.sixAble - itemNext.sixAble) * (Math.ceil(count) - count)
          ),
    [count, item, itemNext]
  );

  useEffect(() => {
    const loadExcelFile = async () => {
      try {
        // 假设你的Excel文件路径是 public/static/data.xlsx
        const response = await fetch("/static/data.xlsx");
        const arrayBuffer = await response.arrayBuffer();

        const data = new Uint8Array(arrayBuffer);
        const workbook = XLSX.read(data, { type: "array" });

        const worksheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[worksheetName];
        const jsonData = XLSX.utils.sheet_to_json(worksheet) as any[];

        // console.log(jsonData);

        setExcelData(
          jsonData
            .filter(
              (json) =>
                !!Object.keys(json).find((k) => json[k].includes("以上"))
            )
            .reduce((arr, json) => {
              const keys = Object.keys(json);
              const value = keys.reduce(
                (j, k) => ({
                  ...j,
                  [k]: Number(
                    json[k]
                      ?.toString()
                      .match(/\d+\.?\d*/g)
                      ?.join("")
                  ),
                }),
                {}
              ) as any;
              return [
                ...arr,
                {
                  score:
                    value[
                      keys.find((k) =>
                        json[k].toString().includes("以上")
                      ) as string
                    ],
                  allAble: value[keys[1]],
                  sixAble: value[keys[2]],
                },
              ];
            }, [])
        );
      } catch (error) {
        console.error("读取Excel文件出错:", error);
      }
    };

    loadExcelFile();
  }, []);

  return (
    <>
      <ConfigProvider
        theme={{
          token: {
            colorPrimary: "#999",
          },
          components: {
            Button: {
              colorPrimary: "#333",
              algorithm: true, // 启用算法
            },
          },
        }}
      >
        <div className="main-box">
          <div className="main-title">
            <h2>中考成绩位次查询</h2>
            <div className="main-extra">
              输入您的中考总分，查询全市及市六区排名
            </div>
          </div>
          <div className="main-content">
            <div className="main-row bold">中考总分</div>
            <div className="main-row">
              <InputNumber
                addonAfter="分"
                min={500}
                max={780}
                precision={2}
                step={0.01}
                onChange={onChange}
              />
            </div>
            <div className="main-row">
              <div className="main-extra">
                请输入500-780之间的分数，支持0.01分精度（如760.25、650.50）
              </div>
            </div>
            <div className="main-row">
              <Button
                className="button"
                type="primary"
                size="middle"
                onClick={() => {
                  setCount(value);
                }}
              >
                查询位次
              </Button>
            </div>
          </div>
          <div className="main-next">
            <div>
              <div className="next-title">您的分数</div>
              <div className="next-content">
                {(count || count === 0) && <>{count.toFixed(2)} 分</>}
              </div>
              <div className="next-extra"></div>
            </div>
            <div>
              <div className="next-title">超过考生</div>
              <div className="next-content">
                {(rankRatio || rankRatio === 0) && <>全市 {rankRatio}%</>}
              </div>
              <div className="next-extra">
                {(rankSixRatio || rankSixRatio === 0) && (
                  <>市六区 {rankSixRatio}%</>
                )}
              </div>
            </div>
            <div>
              <div className="next-title">市六区位次</div>
              <div className="next-content">
                {(rankSix || rankSix === 0) && <>约为第 {rankSix.toLocaleString()} 名</>}
              </div>
            </div>
            <div>
              <div className="next-title">全市位次</div>
              <div className="next-content">
                {(rank || rank === 0) && <>约为第 {rank.toLocaleString()} 名</>}
              </div>
            </div>
          </div>
        </div>
      </ConfigProvider>
    </>
  );
}

export default App;
